package com.readaloud.inverted;


import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import com.readaloud.hibernate.user.Books;
import com.readaloud.indexing.KeyWord;

public class BookParser {
	public Books parsebook(Books book)
	{
		FileInputStream fstream;
		try {
			//if (filepath.isFile()) {
				fstream = new FileInputStream(book.getLocation());

				DataInputStream in = new DataInputStream(fstream);
				BufferedReader br = new BufferedReader(
						new InputStreamReader(in));
				String strLine;
				String[] temp = null;

				while ((strLine = br.readLine()) != null) {

					if (strLine.contains("Title:")) {
						temp = strLine.split(":");
						strLine = temp[1].trim();
						// set in object value setTitle();

						System.out.println("T->" + strLine);
						book.setTitle(strLine);
						temp = null;
					}
					if (strLine.contains("Author:")) {
						temp = strLine.split(":");
						strLine = temp[1].trim();
						// set in object to persist
						System.out.println("A->" + strLine);
						book.setBookAuthor(strLine);
						temp = null;
					}

					if (strLine.contains("Release Date:")) {
						temp = strLine.split(":");
						strLine = temp[1].trim();
						// System.out.println("temp check" + strLine);
						temp = strLine.split("\\[");
						strLine = temp[0].trim();

						// set object
						System.out.println("R->" + strLine);
						book.setReleaseDate(strLine);
						temp = null;	
					}

					if (strLine.contains("Language:")) {
						temp = strLine.split(":");
						strLine = temp[1].trim();

						// set object
						System.out.println("L->" + strLine);
						book.setLanguage(strLine);
						temp = null;
						break;
					}

				}
			//}
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return book;
	}
	
		public Books addKeyword(Books book, String w, int position) {
			if (w == null || w.trim().length() == 0)
				return book;
			else {
				KeyWord kw = book.getKeywords().get(w.trim().toLowerCase());
				if (kw == null) {
					kw = new KeyWord(w.trim().toLowerCase(), position);
					kw.setFrequency(kw.position.size());
					kw.setMean(getAverage(kw));
					kw.setStandardDeviation(kw.stdDev());
					book.getKeywords().put(kw.word, kw);
				} else
					kw.add(position);
				return book;
			}

		}

		public double similarity(Books book, Books doc) {
			if (book.getKeywords() == null || doc.getKeywords() == null)
				return 0.0;

			int total = 0, count = 0;
			if (book.getKeywords().size() > doc.getKeywords().size()) {
				for (KeyWord kw : book.getKeywords().values()) {
					total += kw.position.size();
					if (doc.getKeywords().containsKey(kw.word))
						count += kw.position.size();
				}
			} else {
				for (KeyWord kw : doc.getKeywords().values()) {
					total += kw.position.size();
					if (book.getKeywords().containsKey(kw.word))
						count += kw.position.size();
				}
			}

			// jaccard weighted index
			double r = (double) count / (double) total;

			// rounding
			int ri = (int) (r * 10000.0f);
			r = ((double) ri) / 10000.0f;
			return r;
		}

		public List<KeyWord> keywords(Books book) {
			List<KeyWord> list = new ArrayList<KeyWord>(book.getKeywords().values());
			Collections.sort(list, new Comparator<KeyWord>() {

				@Override
				public int compare(KeyWord w1, KeyWord w2) {
					if (w1.position.size() == w2.position.size())
						return 0;
					else if (w1.position.size() < w2.position.size())
						return 1;
					else
						return -1;
				}
			});

			return list;
		}

		public String toString(Books book) {
			StringBuilder sb = new StringBuilder();
			sb.append("Name: ");
			sb.append(book.getName());
			sb.append("\nFile: ");
			sb.append(book.getLocation());
			sb.append("\nNum words: ");
			sb.append(book.getNumWords());
			sb.append("\nKeywords:\n");

			//TODO: to be removed
			DecimalFormat fmt = new DecimalFormat("#.##");

			for (KeyWord kw : keywords(book)) {
				sb.append(kw.word);
				sb.append(" (n = ");
				sb.append(kw.position.size());
				sb.append(", pos = [");

				double ave = 0.0f;
				for (Integer p : kw.position) {
					ave += p;
					sb.append(p);
					sb.append(",");
				}
				sb.deleteCharAt(sb.length() - 1);
				sb.append("], ");

				ave /= kw.position.size();
				sb.append("mean = ");
				sb.append(fmt.format(ave));
				sb.append(", stdev = ");
				sb.append(fmt.format(kw.stdDev()));
				sb.append(")\n");

			}
			return sb.toString();
		}

		/*public String csvHeader(Books book) {
			StringBuilder sb = new StringBuilder();
			sb.append("name,location,numWords\n");
			sb.append("\"");
			sb.append(book.getName());
			sb.append("\",\"");
			sb.append(book.getLocation());
			sb.append("\",");
			sb.append(book.getNumWords());
			sb.append("\n");

			return sb.toString();
		}*/

		public double getAverage(KeyWord keyword){
			double ave = 0.0f;
			for (Integer p : keyword.position) {
				ave += p;
			}
			ave /= keyword.position.size();
			return ave;
		}
		
		public void csvData(Books book) {
			//StringBuilder sb = new StringBuilder();
			/*sb.append("\n\n");
			sb.append("word, freq, pos (mean), pos (stdev)\n");
*/
			//DecimalFormat fmt = new DecimalFormat("#.##");

			for (KeyWord keyword : keywords(book)) {
				double ave = 0.0f;
				for (Integer p : keyword.position) {
					ave += p;
				}
				ave /= keyword.position.size();
				
				KeyWord keywordObject = new KeyWord();
				keywordObject.setFrequency(keyword.position.size());
				keywordObject.setMean(ave);
				keywordObject.setStandardDeviation(keyword.stdDev());
				
				/*sb.append("\"");
				sb.append(keyword.word);
				sb.append("\",");
				sb.append(keyword.position.size());
				sb.append(",");
				sb.append(fmt.format(ave));
				sb.append(",");
				sb.append(fmt.format(keyword.stdDev()));
				sb.append("\n");*/

			}
		}
}
